package edu.spec.basic.web.filter;

import edu.spec.student.model.Student;
import edu.spec.student.service.iface.IStudentService;
import edu.spec.basic.model.User;
import edu.spec.basic.service.iface.IUserService;
import edu.spec.basic.web.BeanFactoryContext;
import edu.spec.wechat.kit.WechatKit;
import edu.spec.wechat.model.WechatFianlValue;
import edu.spec.wechat.web.WechatContext;
import org.madgecko.basic.kit.BasicKit;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Author       : MadFrog
 * Date         : 2018/3/24 10:22
 * Description  : 重点处理登录请求，对所有请求进行过滤：1、静态资源、微信消息、登录请求直接忽略；2、session不存在的微信请求直接登录；3、session不存在的浏览器请求重定向到登录界面。
 *
 */
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /**
         * Http请求总体分3种
         * A.微信消息
         * B.微信浏览器请求
         * C.常规浏览器请求
         */
        HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
        String url = httpRequest.getRequestURI();
        // A 微信消息、静态资源、登录请求直接pass
        if (url.indexOf("resources")>0 || url.indexOf("wechat")>0 || url.indexOf("login")>0){
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        HttpServletResponse httpResponse = (HttpServletResponse)servletResponse;
        HttpSession session = httpRequest.getSession();

        String agent = httpRequest.getHeader("User-Agent");
        Object user = session.getAttribute("user");

        //检查用户是否登录
        if (user==null){
            // B 微信浏览器端的请求
            if (agent!=null && agent.toLowerCase().indexOf("micromessenger")>=0){
                String code = servletRequest.getParameter("code");
                String state = servletRequest.getParameter("state");
                System.out.println("code & state : " + code + ", " + state);


                if (code!=null&&"1".equals(state)){
                    //判断是教师行为还是学生行为
                    //微信端跳转以后，code和state都有了。
                    String openId = WechatKit.getOpenIdByCode(code);
                    System.out.println("openId : " + openId);
                    session.setAttribute("openId", openId);
                    if (url.indexOf("student")>0){
                        IStudentService studentService = (IStudentService) BeanFactoryContext.getService("studentService");
                        Student student = studentService.loadByOpenId(openId);
                        if(student==null){
                            httpResponse.sendRedirect(httpRequest.getContextPath()+"/student/bind");
                        }
                        session.setAttribute("user", student);
                    }else if(url.indexOf("teacher")>0){
                        IUserService userService = (IUserService) BeanFactoryContext.getService("userService");
                        User teacher = userService.loadByOpenId(openId);
                        if(teacher==null){
                            httpResponse.sendRedirect(httpRequest.getContextPath()+"/teacher/bind");
                        }
                        session.setAttribute("user", teacher);
                    }
                } else {
                    // 如果是绑定操作请求，忽略
                    if(!(url.indexOf("bind")>0)){
                        //第一次访问链接的时候，code、state都为空。
                        String path = httpRequest.getRequestURL().toString();
                        String query = httpRequest.getQueryString();
                        if(!BasicKit.isEmpty(query)){
                            path += "?" + query;
                        }
                        String uri = WechatFianlValue.AUTH_GET_CODE;
                        uri = uri.replace("APPID", WechatContext.getInstance().getAppID())
                                .replace("REDIRECT_URI", path   )
                                .replace("SCOPE", "snsapi_base")
                                .replace("STATE", "1");
                        System.out.println(path);
                        httpResponse.sendRedirect(uri);
                        System.out.println("httpResponse.sendRedirect(uri) : " + uri);
                        //URLEncoder.encode(path, "UTF-8")
                    }
                }
            } else {
                // C 普通浏览器请求
                httpResponse.sendRedirect(httpRequest.getContextPath()+"/admin/login");
                return;
            }
        }
        filterChain.doFilter(servletRequest, servletResponse);
        return;
    }

    @Override
    public void destroy() {

    }
}